﻿using System;
using System.Collections.Generic;
using System.Windows;
using System.Windows.Input;
using IronCow;
using Milkify.Interfaces;
using Milkify.Input;
using System.ComponentModel;
using System.Windows.Data;

namespace Milkify.Controllers
{
    public class SettingsController : Controller
    {
        private ISettingsView mView;

        // The Settings class designer generates the Settings class as an internal class, 
        // and WPF needs public properties for data-binding to work, so we just expose this
        // as a System.Object.
        public object Settings
        {
            get { return Properties.Settings.Default; }
        }

        private List<string> mSkins = new List<string>();
        public IEnumerable<string> Skins
        {
            get { return mSkins; }
        }

        private string mSelectedSkin;
        public string SelectedSkin
        {
            get { return mSelectedSkin; }
            set
            {
                mSelectedSkin = value;
                OnSelectedSkinChanged();
            }
        }

        public SettingsController(ControllerContext context, Rtm rtm, IViewContainer viewContainer, IViewFactory viewFactory)
            : base(context, rtm, viewContainer)
        {
            mView = (ISettingsView)viewFactory.Create("Settings");
            mView.Cancel += new EventHandler(View_Cancel);
            mView.Save += new EventHandler(View_Save);
        }

        public override void Execute()
        {
            mView.ViewData = this;

            mSkins.Add("MilkifySkin");
            mSkins.Add("NoSkin");
            ICollectionView skinsView = CollectionViewSource.GetDefaultView(mSkins);
            skinsView.MoveCurrentToFirst();
            skinsView.CurrentChanged += new EventHandler(SkinsView_CurrentChanged);

            ViewContainer.NavigateToView(mView);
            CommandManager.InvalidateRequerySuggested();
        }

        private void View_Cancel(object sender, EventArgs e)
        {
            Properties.Settings.Default.Reload();
            ApplyImmediateSettings();
            CommandManager.InvalidateRequerySuggested();
        }

        private void View_Save(object sender, EventArgs e)
        {
            Properties.Settings.Default.Save();
            ApplyImmediateSettings();
            CommandManager.InvalidateRequerySuggested();
        }

        private void SkinsView_CurrentChanged(object sender, EventArgs e)
        {
            string skinName = ((ICollectionView)sender).CurrentItem as string;
            SelectedSkin = skinName;
        }

        private void OnSelectedSkinChanged()
        {
            if (!string.IsNullOrEmpty(mSelectedSkin))
            {
                string skinUri = string.Format("Skins/{0}.xaml", mSelectedSkin);
                ChangeSkin(skinUri);
            }
        }

        private static void ChangeSkin(string skinUri)
        {
            Uri skinUriRelative = new Uri(skinUri, UriKind.Relative);

            int skinIndex = App.Current.Resources.MergedDictionaries.Count - 1;
            ResourceDictionary current = (ResourceDictionary)App.Current.Resources.MergedDictionaries[skinIndex];
            if (current.Source == skinUriRelative)
                return;

            ResourceDictionary skin = (ResourceDictionary)App.LoadComponent(skinUriRelative);
            App.Current.Resources.MergedDictionaries.RemoveAt(skinIndex);
            App.Current.Resources.MergedDictionaries.Add(skin);
        }

        private void ApplyImmediateSettings()
        {
            ViewContainer.ShowInTaskbar = Properties.Settings.Default.ShowInTaskbar;

            if (Properties.Settings.Default.UseProxy)
            {
                string address = Properties.Settings.Default.ProxyAddress;
                Rtm.Client.Proxy = new System.Net.WebProxy(address);
            }
            else
            {
                Rtm.Client.Proxy = null;
            }

            ViewContainer.IsPinnedToDesktop = Properties.Settings.Default.PinToDesktop;
        }
    }
}
